package com.yzc.rabbit;

import com.yzc.apis.logClient.MainOrderLogClient;
import com.yzc.constants.MqConstants;
import com.yzc.mapper.TicketAttractionOrderMapper;
import com.yzc.message.RollbackInventoryMessage;
import com.yzc.model.entity.log.OrderStatusLog;
import com.yzc.model.vo.ticket_order.v_AttractionOrderVo;
import com.yzc.redis.RedisUtil;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;

import static com.yzc.constant.RedisConstant.*;

@Slf4j
@Service
@RequiredArgsConstructor
public class InventoryService {

    private final TicketAttractionOrderMapper attractionOrderMapper;
    private final RabbitTemplate rabbitTemplate;
    private final MainOrderLogClient mainOrderLogClient;
    private final RedisUtil redisUtil;

    /**
     * 回滚库存
     *
     * @param orderId 订单ID
     */
    @Transactional
    public void rollbackInventory(Long orderId) {
        // 从缓存中查询订单信息
        v_AttractionOrderVo attractionOrderVo = (v_AttractionOrderVo) redisUtil.get(ATTRACTION_ORDER_VO + orderId);
        if (attractionOrderVo == null) {
            // 如果缓存中没有，再从数据库中查询
            attractionOrderVo = attractionOrderMapper.selectUserInfoByorderId(orderId);
            if (attractionOrderVo == null) {
                log.error("未找到订单信息，订单ID: {}", orderId);
                return;
            }
            // 将查询结果存储到缓存中
            redisUtil.set(ATTRACTION_ORDER_VO + orderId, attractionOrderVo, CACHE_EXPIRE_TIME);
        }

        // 幂等性检查：检查库存是否已经回滚
        if (isInventoryRolledBack(orderId)) {
            log.info("库存已回滚，无需重复操作，订单ID: {}", orderId);
            return;
        }

        // 发送回滚消息
        RollbackInventoryMessage message = new RollbackInventoryMessage();
        message.setOrderId(orderId);
        message.setProductId(attractionOrderVo.getAttractionId());
        message.setQuantity(attractionOrderVo.getTicketCount());

        try {
            // 发送消息到队列
            rabbitTemplate.convertAndSend(
                    MqConstants.ROLLBACK_INVENTORY_EXCHANGE, // 交换机名称
                    "rollback.inventory",                   // 路由键
                    message                                 // 消息内容
            );
            log.info(" [x] 成功发送回滚库存消息，订单ID: {}", orderId);

            // 记录回滚日志
            OrderStatusLog orderStatusLog = new OrderStatusLog();
            orderStatusLog.setOrderId(orderId);
            orderStatusLog.setStatus(attractionOrderVo.getOrderStatus());
            orderStatusLog.setOperator("system");
            orderStatusLog.setRemark("库存回滚");
            orderStatusLog.setCreateTime(new Date());
            mainOrderLogClient.createOrderLog(orderStatusLog,null);

            // 更新缓存中的库存回滚状态
            redisUtil.set(INVENTORY_ROLLBACK_STATUS + orderId, true, CACHE_EXPIRE_TIME);
        } catch (Exception e) {
            log.error("发送回滚库存消息失败，订单ID: {}", orderId, e);
            throw new RuntimeException("发送回滚库存消息失败", e);
        }
    }

    /**
     * 检查库存是否已经回滚
     */
    boolean isInventoryRolledBack(Long orderId) {
        // 先从缓存中获取库存回滚状态
        Boolean isRolledBack = (Boolean) redisUtil.get(INVENTORY_ROLLBACK_STATUS + orderId);
        if (isRolledBack != null) {
            return isRolledBack;
        }
        try {
            isRolledBack = mainOrderLogClient.getOrderLog(orderId).getData();
        } catch (Exception e) {
            log.error("查询库存回滚日志失败，订单ID: {}", orderId, e);
            return false;
        }
        // 将查询结果缓存
        redisUtil.set(INVENTORY_ROLLBACK_STATUS + orderId, isRolledBack, CACHE_EXPIRE_TIME);
        return isRolledBack;
    }

}
